package blackeagle.ems.entities;

import blackeagle.ems.dal.DataClass;
import blackeagle.ems.dal.DataField;
import blackeagle.ems.dal.DataRecord;
import blackeagle.ems.dal.MethodType;
import blackeagle.ems.dal.Where;

/**
 * A class representing a department.
 */
@DataClass(dataName="DEPARTMENT")
public final class Department extends DataRecord<Department> {
    private Integer id,leadId;
    private String name;
    
    /**
     * The default 0-argument constructor. Creates a new instance of the Department-class.
     */
    public Department(){}
    /**
     * Creates a new instance of the Department-class.
     * @param name The name to assign to the new Department.
     */
    public Department(String name){
        this.setName(name);
    }
    
    /**
     * A static class containing read-only fields with column names.
     */
    public static class Columns{
        public static final String Id = "id";
        public static final String LeadId = "leadid";
        public static final String Name = "name";
        
        private Columns(){}
    }
    
    /**
     * Gets the id of this department.
     * @return An integer containing the id of this department.
     */
    @DataField(fieldName="id", methodType=MethodType.Getter, isPrimary=true, autoIncrement=true)
    public Integer getId(){
        return this.id;
    }
    
    /**
     * Sets the id of this department
     * @param value A positive integer.
     */
    @DataField(fieldName="id", methodType=MethodType.Setter, isPrimary=true, autoIncrement=true)
    public void setId(Integer value){
        if(value>0){
            this.id=value;
            this._isDirty=true;
        }        
    }
    
    /**
     * Attempts to return the leader of this department.
     * @return An Employee-record from the database if successful; otherwise <code>null</code>
     */
    public Employee getLead(){
        Employee entity = new Employee().load(this.leadId);
        return (entity.isNew()?null:entity);
    }
    
    /**
     * Attempts to set the leader of this Department.
     * @param employee The employee to set as leader for this department.
     */
    public void setLead(Employee employee){
        Integer employeeId = employee.getId();
        this.setLeadId(employeeId);
    }
    
    /**
     * Gets the lead id of this department.
     * @return An integer containing the id of this department.
     */
    @DataField(fieldName="leadid", methodType=MethodType.Getter)
    public Integer getLeadId(){
        return this.leadId;
    }
    
    /**
     * Sets the lead id of this department.
     * @param value A positive integer.
     */
    @DataField(fieldName="leadid", methodType=MethodType.Setter)
    public void setLeadId(Integer value){
        if(value>0){
            this.leadId = value;
            this._isDirty=true;
        }
    }
    
    /**
     * Gets the name of this department.
     * @return A String containing the name of this department.
     */
    @DataField(fieldName="name", methodType=MethodType.Getter)
    public String getName(){
        return this.name;
    }
    
    /**
     * Sets the name of this department.
     * @param value A String containing the name of this department.
     */
    @DataField(fieldName="name", methodType=MethodType.Setter)
    public void setName(String value){
        if(value!=null&&value.length()>0){
            this.name=value;
            this._isDirty=true;
        }
    }
    
    /**
     * Fetches all the employees assigned to this Department.
     * @return An EmployeeCollection containing all the employees assigned to this department.
     */
    public EmployeeCollection getAssignedEmployees(){
        return new EmployeeCollection()
                .where(new Where(Employee.Columns.DepartmentId, this.id))
                .load();
    }
    
    /**
     * Fetches all the domains structured under this department.
     * @return A DomainCollection containing all the domains structured under this department.
     */
    public DomainCollection getDomains(){
        return new DomainCollection()
                .where(new Where(Domain.Columns.DepartmentId, this.id))
                .load();
    }
    
    /**
     * Fetches all the projects linked to this department.
     * @return A ProjectCollection containing all the projects linked to this department.
     */
    public ProjectCollection getProjects(){
        return new ProjectCollection()
                .where(new Where(Project.Columns.DepartmentId, this.id))
                .load();
    }
    
    @Override
    public boolean equals(Object obj){
        if(obj instanceof Department){
            Department d = (Department)obj;
            if(this.name.equals(d.getName())){
                return true;
            }
        }
        
        return false;
    }
    
    @Override
    public String toString(){
        return this.name;
    }
}